/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package main.game;

import java.util.LinkedHashMap;
import java.util.Map;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.NoneScoped;

enum ProgressionType {

    PT_NONE,
    PT_LIMITED_ARITHMETIC, PT_LIMITED_GEOMETRIC,
    PT_UNLIMITED_ARITHMETIC, PT_UNLIMITED_GEOMETRIC
};

enum RaspasExitType {

    RE_SIMPLE, RE_HARD, RE_STRICT, RE_SPECIAL
};

enum PreferenceGameType {

    PGT_SOCHI, PGT_LENINGRAD
};

/**
 *
 * @author vova
 */
@ManagedBean
@NoneScoped
public class GameConventions implements Cloneable {

    public GameConventions() {
        set_PGT_SOCHI();
    }

    @Override
    public GameConventions clone() {
        GameConventions cloned = new GameConventions();

        cloned.poolLength = poolLength;
        cloned.whistFullPrice = whistFullPrice;
        cloned.stalingrad = stalingrad;
        cloned.gentlemanWhist = gentlemanWhist;
        cloned.gameWithoutThree = gameWithoutThree;
        cloned.progression = progression;
        cloned.progressionFactor = progressionFactor;
        cloned.exitFromRaspas = exitFromRaspas;
        cloned.pointsPerTrickOnRaspas = pointsPerTrickOnRaspas;
        cloned.commonPool = commonPool;

        return cloned;
    }

    /**
     * Установка полей конвенции по умолчанию для указанного типа игры
     * @param gameType тип игры
     * @throws GameControllerException неверный тип игры
     */
    public void setDefaultConventions(PreferenceGameType gameType) throws GameControllerException {
        switch (gameType) {
            case PGT_SOCHI:
                set_PGT_SOCHI();
                break;

            case PGT_LENINGRAD:
                set_PGT_LENINGRAD();
                break;

            default:
                throw new GameControllerException("Неизвестная конвенция");
        }
    }
    
    private void set_PGT_SOCHI() {
        poolLength = 30;
        whistFullPrice = true;
        stalingrad = true;
        gentlemanWhist = false;
        gameWithoutThree = false;
        progression = ProgressionType.PT_LIMITED_ARITHMETIC;
        progressionFactor = 1;
        exitFromRaspas = RaspasExitType.RE_SIMPLE;
        pointsPerTrickOnRaspas = 2;
        commonPool = false;
    }
    
    private void set_PGT_LENINGRAD() {
        poolLength = 30;
        whistFullPrice = false;
        stalingrad = false;
        gentlemanWhist = true;
        gameWithoutThree = true;
        progression = ProgressionType.PT_NONE;
        progressionFactor = 1;
        exitFromRaspas = RaspasExitType.RE_SIMPLE;
        pointsPerTrickOnRaspas = 2;
        commonPool = true;
    }

    /**
     * Игра продолжается до среднего в пуле, или до указанной у каждого игрока
     * @return полная/до среднего
     */
    public boolean isCommonPool() {
        return commonPool;
    }

    /**
     * Установка конца игры по пуле. Все игроки до указанной или до среднего
     * @param commonPool полная/до среднего
     */
    public void setCommonPool(boolean commonPool) {
        this.commonPool = commonPool;
    }

    /**
     * Получение типа выхода из распасов
     * @return тип выхода
     */
    public RaspasExitType getExitFromRaspas() {
        return exitFromRaspas;
    }

    /**
     * Тип выхода из распасов
     * @param exitFromRaspas простой, усложненный, ужесточенный
     */
    public void setExitFromRaspas(RaspasExitType exitFromRaspas) {
        this.exitFromRaspas = exitFromRaspas;
    }

    /**
     * Разрешен уход без 3х?
     * @return возможность уйти без трех
     */
    public boolean isGameWithoutThree() {
        return gameWithoutThree;
    }

    /**
     * Установка возможности уйти без трех
     * @param gameWithoutThree можно/нельзя уходить без трех
     */
    public void setGameWithoutThree(boolean gameWithoutThree) {
        this.gameWithoutThree = gameWithoutThree;
    }

    /**
     * Получения типа виста
     * @return жлобский/джентельменский
     */
    public boolean isGentlemanWhist() {
        return gentlemanWhist;
    }

    /**
     * Установка типа виста
     * @param gentlemanWhist джентельменский/ждобский
     */
    public void setGentlemanWhist(boolean gentlemanWhist) {
        this.gentlemanWhist = gentlemanWhist;
    }

    /**
     * Количество очков на распасах за взятку
     * @return количество очков
     */
    public int getPointsPerTrickOnRaspas() {
        return pointsPerTrickOnRaspas;
    }

    /**
     * Установка количества очков на распасах за взятку
     * @param pointsPerTrickOnRaspas новое количество очков за взятку
     */
    public void setPointsPerTrickOnRaspas(int pointsPerTrickOnRaspas) {
        this.pointsPerTrickOnRaspas = pointsPerTrickOnRaspas;
    }

    /**
     * Длина пули
     * @return длина пули
     */
    public int getPoolLength() {
        return poolLength;
    }

    /**
     * Устанвка длины пули
     * @param poolLength длина пули
     */
    public void setPoolLength(int poolLength) {
        this.poolLength = poolLength;
    }

    /**
     * Получение типа прогрессии на распасах
     * @return тип прогрессии
     */
    public ProgressionType getProgression() {
        return progression;
    }

    /**
     * Установка типа прогрессии на распасах
     * @param progression новый тип ропгрессии
     */
    public void setProgression(ProgressionType progression) {
        this.progression = progression;
    }

    /**
     * Получение коэффициента прогрессии на распасах
     * @return коэффициент прогрессии
     */
    public int getProgressionFactor() {
        return progressionFactor;
    }

    /**
     * Установка коэффициента прогрессии на распасах
     * @param progressionFactor новый коэффициент прогрессии
     */
    public void setProgressionFactor(int progressionFactor) {
        this.progressionFactor = progressionFactor;
    }

    /**
     * Обязателен сталинград (вист на 6 пик)
     * @return да/нет
     */
    public boolean isStalingrad() {
        return stalingrad;
    }

    /**
     * Установка/запрет обязательного сталинграда (вист на 6 пик)
     * @param stalingrad да/нет
     */
    public void setStalingrad(boolean stalingrad) {
        this.stalingrad = stalingrad;
    }

    /**
     * Тип ответственности на висте
     * @return ответственный/полуответственный
     */
    public boolean isWhistFullPrice() {
        return whistFullPrice;
    }

    /**
     * Установка ответственности на висте
     * @param whistFullPrice ответственный/полуответственный
     */
    public void setWhistFullPrice(boolean whistFullPrice) {
        this.whistFullPrice = whistFullPrice;
    }
    
    public Map<String,Object> getProgressionType(){
        Map<String,Object> condimetItem = new LinkedHashMap<String, Object>();
        condimetItem.put("Net",ProgressionType.PT_NONE);
        condimetItem.put("Limitirovanaya arifmeti4eskaya",ProgressionType.PT_LIMITED_ARITHMETIC);
        condimetItem.put("Limitirovanaya geometricheskaya",ProgressionType.PT_LIMITED_GEOMETRIC);
        condimetItem.put("Ne limitirovannaya arifmeti4eskaya",ProgressionType.PT_UNLIMITED_ARITHMETIC);
        condimetItem.put("Ne limitirovannaya geometricheskaya",ProgressionType.PT_UNLIMITED_GEOMETRIC);
        return condimetItem;
    }
    public Map<String,Object> getRaspasExitType(){
        Map<String,Object> condimetItem = new LinkedHashMap<String, Object>();
        condimetItem.put("Prosto",RaspasExitType.RE_SIMPLE);
        condimetItem.put("Slojno",RaspasExitType.RE_HARD);
        condimetItem.put("Strogiy",RaspasExitType.RE_STRICT);
        condimetItem.put("Special",RaspasExitType.RE_SPECIAL);
        return condimetItem;
    }
    
    // длина пули
    private int poolLength;
    // вист ответственный/полуответственный
    private boolean whistFullPrice;
    // сталинград
    private boolean stalingrad;
    // джентельменский/жлобский вист
    private boolean gentlemanWhist;
    // уход без 3х
    private boolean gameWithoutThree;
    // прогрессия на распасах
    ProgressionType progression;
    // коэффициент прогрессии
    int progressionFactor;
    // выход из распасов
    RaspasExitType exitFromRaspas;
    // очков в гору за взятку на распасах
    int pointsPerTrickOnRaspas;
    // "общая" пулька (false - каждый играет до указанной пули, true - все играют до среднего пули)
    boolean commonPool;
}
